#include "stdafx.h"
#include "Appraisal.h"
#include "event.h"
#include "role.h"

using namespace BAA;


void BAA::Appraisal::AppraiseEvent(Event * event)
{
	// filter based on relevance
	std::vector<Value*>* values;			// to hold value list for a given watch
	ValueValueMap triggeredValues;  // holds a list of values activated by the event


	if(event->getConsequences() != NULL)
	{		
		// for each of the consequences, see if a value watch exists.
		StringFloatMap::iterator it;

		for(StringFloatMap::iterator it = event->getConsequences()->begin();
			it != event->getConsequences()->end(); ++it)
		{

			// get any watches for this consequence
			values = &(mConsequenceMap[it->first]);

			// test to see if watch exists
			if(values !=NULL)
			{
				// a watch does exists, ready the values for appraisal
				// add each value to the triggered list
				// using map forces value to only be added once.
				for(unsigned int j = 0; j < values->size(); ++j)
					triggeredValues[values->at(j)]=values->at(j);

			}
		}// end for
	}


	if((event->getTargets()) != NULL)
	{

		// for each target, see if a value watch exits
		for(unsigned int i = 0; i < event->getTargets()->size(); ++i)
		{
			// get any value watch for the target
			values = mTargetValuesMap[(*(event->getTargets()))[i]];

			// are we watching this target?
			if(values != NULL)
			{
				// we are watching this target
				// add event to be appraised by its associated Values.
				for(unsigned int j = 0; j < values->size(); ++j)
					triggeredValues[values->at(j)]=values->at(j);
			}

		}
	}

	// we now have a list of each of the Values. 
	// For each, return an appraisal of the event. 

	// TODO - EMOTIONAL


	for(ValueValueMap::const_iterator it = triggeredValues.begin();
		it !=  triggeredValues.end(); ++it)
	{
		EmotionalMemory * mem = (*it).first->AppraiseEvent(event);

		if(mem != NULL)
		{
			mem->RoleParent()->Self()->AddToAppraisedEvents(mem);
		}

	}



}

void BAA::Appraisal::AddValue( Value * value )
{
	if(value == NULL)
		return;
	// for each consequence, add watch

	 StringFloatMap * consequences = value->Consequences();

	if(value->WatchConsequences() && consequences != NULL)
	{
		// for each consequence, add the mapping to the appraisal.
		StringFloatMap::const_iterator it;

		for(it = consequences->begin(); it != consequences->end(); ++it)
			AddConsequenceWatch((*it).first, value);
	}
	else if(value->WatchTargets())
	{
		
		for(AgentPointerMap::iterator it = value->RoleParent()->Targets()->begin(); it != value->RoleParent()->Targets()->end(); ++it)
		{
			AddTargetWatch(it->second, value);
		}
	}
}

void BAA::Appraisal::AddConsequenceWatch(std::string consequence,Value * values )
{
	// add value to watch for this consequence.
	mConsequenceMap[consequence].push_back(values);
}

float BAA::Appraisal::CalculateUtilityOfAction(Action* action)
{
	// filter based on relevance
	std::vector<Value*>* values = NULL;			// to hold value list for a given watch
	ValueValueMap triggeredValues;  // holds a list of values activated by the event


	
	//if(action->Consequences() != NULL)
	//{		
	//	// for each of the consequences, see if a value watch exists.
	//	StringFloatMap::iterator it;

	//	for(StringFloatMap::iterator it = action->Consequences()->begin();
	//		it != action->Consequences()->end(); ++it)
	//	{

	//		// get any watches for this consequence
	//		values = &(mConsequenceMap[it->first]);

	//		// test to see if watch exists
	//		if(values !=NULL)
	//		{
	//			// a watch does exists, ready the values for appraisal
	//			// add each value to the triggered list
	//			// using map forces value to only be added once.
	//			for(unsigned int j = 0; j < values->size(); ++j)
	//				triggeredValues[values->at(j)]=values->at(j);
	//		}
	//	}// end for
	//}


	if(action->GetTargets() != NULL)
	{
		
		// for each target, see if a value watch exits
		for(AgentPointerMap::iterator it  = action->GetTargets()->begin();
			it != action->GetTargets()->end(); ++it)
		{

			// get any value watch for the target
			values = mTargetValuesMap[it->second];

			// are we watching this target?
			if(values != NULL)
			{
				// we are watching this target
				// add event to be appraised by its associated Values.
				for(unsigned int j = 0; j < values->size(); ++j)
				{
					triggeredValues[values->at(j)]=values->at(j);
				}// end for

			}// end if

		}// end for
	}

	// we now have a list of each of the Values. 
	// For each, return an appraisal of the event. 

	float utility =0;

	for(ValueValueMap::const_iterator it = triggeredValues.begin();it !=  triggeredValues.end(); ++it)
	{
		utility+= (*it).first->CalculateUtility(action);
	}


	// look for actions

	/// mCurrentGoal->CalculateUtilityForAction(currentNode->action);

	
	return utility;

}

void BAA::Appraisal::AddGoal( Goal * goal )
{
	if(goal == NULL)
		return;


	for(AgentPointerMap::iterator it  = goal->ParentRole()->Targets()->begin();
		it != goal->ParentRole()->Targets()->end(); ++it)
		mTargetGoalsMap[it->second].push_back(goal);


}